package com.sj.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sj.common.bean.LocalUser;
import com.sj.common.dto.menu.SysMenuDto;
import com.sj.common.lang.ApiResult;
import com.sj.common.lang.Const;
import com.sj.common.lang.RedisConst;
import com.sj.entity.SysMenu;
import com.sj.entity.User;
import com.sj.interceptor.AuthCheck;
import com.sj.service.SysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 前端控制器
 * </p>
 *
 * @author 孙峻
 * @since 2022-03-09
 */
@RestController
@RequestMapping("/sysMenu")
@Api(tags = "菜单模块")
public class SysMenuController {

    @Autowired
    private SysMenuService sysMenuService;

    @AuthCheck
    @ApiOperation("根据用户id获取权限列表")
    @GetMapping("/user/list")
    public ApiResult getUserMenuList() {
        User user = LocalUser.getUser();
        return ApiResult.success(sysMenuService.getMenuListByUserId(user.getId()));
    }

    @GetMapping("/list/{roleId}")
    @ApiOperation("根据角色id获取权限列表")
    @AuthCheck
    @Cacheable(cacheNames = "menu-list", keyGenerator = RedisConst.REDIS_SJ_KEY_GENERATOR)
    public ApiResult getMenuListByRoleId(@PathVariable Integer roleId) {
        List<SysMenu> list = sysMenuService.getMenuListByRoleId(roleId);
        return ApiResult.success(list);
    }

    /**
     * 获取菜单列表
     *
     * @param type 类型 all_menu 获取所有菜单  否则 获取 目录 和 菜单 按钮不要
     * @return
     */
    @AuthCheck
    @ApiOperation("获取菜单列表")
    @GetMapping("/list/{type}/{showIsForBidden}")
    @Cacheable(cacheNames = "menu-list", keyGenerator = RedisConst.REDIS_SJ_KEY_GENERATOR)
    public ApiResult getSysMenuList(@PathVariable String type, @PathVariable Boolean showIsForBidden) {
        // 查最高级菜单
        LambdaQueryWrapper<SysMenu> lambdaQuery = Wrappers.<SysMenu>lambdaQuery();
        // 如果不显示已禁用，那么只查为禁用的
        if (!showIsForBidden) {
            lambdaQuery.eq(SysMenu::getStatus, Boolean.TRUE);
        }
        lambdaQuery.eq(SysMenu::getParentId, Const.MENU_PARENT).orderBy(true , true , SysMenu::getOrderNum);
        List<SysMenu> list = sysMenuService.list(lambdaQuery);
        List<SysMenuDto> result = this.sysMenu2Dto(list, showIsForBidden, type);
        return ApiResult.success(result);
    }

    private List<SysMenuDto> sysMenu2Dto(List<SysMenu> list, Boolean showIsForBidden, String type) {
        List<SysMenuDto> resultList = new ArrayList<>();
        if (list.size() == 0) {
            return resultList;
        }
        resultList = list.stream().map(temp -> {
            SysMenuDto sysMenuDto = new SysMenuDto();
            BeanUtil.copyProperties(temp, sysMenuDto, "children", "hasChildren");
            LambdaQueryWrapper<SysMenu> lambdaQuery = Wrappers.<SysMenu>lambdaQuery();
            // 如果不显示已禁用，那么只查为禁用的
            if (!showIsForBidden) {
                lambdaQuery.eq(SysMenu::getStatus, Boolean.TRUE);
            }
            if (!StrUtil.equals(type, Const.All)) {
                lambdaQuery.and(cus -> {
                    cus.eq(SysMenu::getType, Const.MENU_CATALOG).or().eq(SysMenu::getType, Const.MENU_MENU);
                });
            }
            lambdaQuery.eq(SysMenu::getParentId, sysMenuDto.getId());
            sysMenuDto.setChildren(this.sysMenu2Dto(sysMenuService.list(lambdaQuery), showIsForBidden, type));
            sysMenuDto.setHasChildren(sysMenuDto.getChildren().size() > 0);
            return sysMenuDto;
        }).collect(Collectors.toList());

        return resultList;
    }

    @PutMapping("/save")
    @ApiOperation("添加菜单")
    @AuthCheck
    @CacheEvict(cacheNames = {"menu-list"}, keyGenerator = RedisConst.REDIS_SJ_KEY_GENERATOR, allEntries = true)
    public ApiResult addSysMenu(@RequestBody SysMenuDto sysMenuDto) {
        SysMenu sysMenu = new SysMenu();
        BeanUtil.copyProperties(sysMenuDto, sysMenu);
        boolean result = sysMenuService.saveOrUpdate(sysMenu);
        if (result) {
            return ApiResult.success("保存成功");
        }
        return ApiResult.error("保存失败");
    }

}
